home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / sre_parse.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  18.7 KB  |  918 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import sys
  5. from sre_constants import *
  6.  
  7. def set(seq):
  8.     s = { }
  9.     for elem in seq:
  10.         s[elem] = 1
  11.     
  12.     return s
  13.  
  14. SPECIAL_CHARS = '.\\[{()*+?^$|'
  15. REPEAT_CHARS = '*+?{'
  16. DIGITS = set('0123456789')
  17. OCTDIGITS = set('01234567')
  18. HEXDIGITS = set('0123456789abcdefABCDEF')
  19. WHITESPACE = set(' \t\n\r\x0b\x0c')
  20. ESCAPES = {
  21.     '\\a': (LITERAL, ord('\x07')),
  22.     '\\b': (LITERAL, ord('\x08')),
  23.     '\\f': (LITERAL, ord('\x0c')),
  24.     '\\n': (LITERAL, ord('\n')),
  25.     '\\r': (LITERAL, ord('\r')),
  26.     '\\t': (LITERAL, ord('\t')),
  27.     '\\v': (LITERAL, ord('\x0b')),
  28.     '\\\\': (LITERAL, ord('\\')) }
  29. CATEGORIES = {
  30.     '\\A': (AT, AT_BEGINNING_STRING),
  31.     '\\b': (AT, AT_BOUNDARY),
  32.     '\\B': (AT, AT_NON_BOUNDARY),
  33.     '\\d': (IN, [
  34.         (CATEGORY, CATEGORY_DIGIT)]),
  35.     '\\D': (IN, [
  36.         (CATEGORY, CATEGORY_NOT_DIGIT)]),
  37.     '\\s': (IN, [
  38.         (CATEGORY, CATEGORY_SPACE)]),
  39.     '\\S': (IN, [
  40.         (CATEGORY, CATEGORY_NOT_SPACE)]),
  41.     '\\w': (IN, [
  42.         (CATEGORY, CATEGORY_WORD)]),
  43.     '\\W': (IN, [
  44.         (CATEGORY, CATEGORY_NOT_WORD)]),
  45.     '\\Z': (AT, AT_END_STRING) }
  46. FLAGS = {
  47.     'i': SRE_FLAG_IGNORECASE,
  48.     'L': SRE_FLAG_LOCALE,
  49.     'm': SRE_FLAG_MULTILINE,
  50.     's': SRE_FLAG_DOTALL,
  51.     'x': SRE_FLAG_VERBOSE,
  52.     't': SRE_FLAG_TEMPLATE,
  53.     'u': SRE_FLAG_UNICODE }
  54.  
  55. class Pattern:
  56.     
  57.     def __init__(self):
  58.         self.flags = 0
  59.         self.open = []
  60.         self.groups = 1
  61.         self.groupdict = { }
  62.  
  63.     
  64.     def opengroup(self, name = None):
  65.         gid = self.groups
  66.         self.groups = gid + 1
  67.         if name is not None:
  68.             ogid = self.groupdict.get(name, None)
  69.             if ogid is not None:
  70.                 raise error, 'redefinition of group name %s as group %d; was group %d' % (repr(name), gid, ogid)
  71.             
  72.             self.groupdict[name] = gid
  73.         
  74.         self.open.append(gid)
  75.         return gid
  76.  
  77.     
  78.     def closegroup(self, gid):
  79.         self.open.remove(gid)
  80.  
  81.     
  82.     def checkgroup(self, gid):
  83.         if gid < self.groups:
  84.             pass
  85.         return gid not in self.open
  86.  
  87.  
  88.  
  89. class SubPattern:
  90.     
  91.     def __init__(self, pattern, data = None):
  92.         self.pattern = pattern
  93.         if data is None:
  94.             data = []
  95.         
  96.         self.data = data
  97.         self.width = None
  98.  
  99.     
  100.     def dump(self, level = 0):
  101.         nl = 1
  102.         seqtypes = (type(()), type([]))
  103.         for op, av in self.data:
  104.             print level * '  ' + op,
  105.             nl = 0
  106.             if op == 'in':
  107.                 print 
  108.                 nl = 1
  109.                 for op, a in av:
  110.                     print (level + 1) * '  ' + op, a
  111.                 
  112.             elif op == 'branch':
  113.                 print 
  114.                 nl = 1
  115.                 i = 0
  116.                 for a in av[1]:
  117.                     if i > 0:
  118.                         print level * '  ' + 'or'
  119.                     
  120.                     a.dump(level + 1)
  121.                     nl = 1
  122.                     i = i + 1
  123.                 
  124.             elif type(av) in seqtypes:
  125.                 for a in av:
  126.                     if isinstance(a, SubPattern):
  127.                         if not nl:
  128.                             print 
  129.                         
  130.                         a.dump(level + 1)
  131.                         nl = 1
  132.                         continue
  133.                     print a,
  134.                     nl = 0
  135.                 
  136.             else:
  137.                 print av,
  138.                 nl = 0
  139.             if not nl:
  140.                 print 
  141.                 continue
  142.         
  143.  
  144.     
  145.     def __repr__(self):
  146.         return repr(self.data)
  147.  
  148.     
  149.     def __len__(self):
  150.         return len(self.data)
  151.  
  152.     
  153.     def __delitem__(self, index):
  154.         del self.data[index]
  155.  
  156.     
  157.     def __getitem__(self, index):
  158.         return self.data[index]
  159.  
  160.     
  161.     def __setitem__(self, index, code):
  162.         self.data[index] = code
  163.  
  164.     
  165.     def __getslice__(self, start, stop):
  166.         return SubPattern(self.pattern, self.data[start:stop])
  167.  
  168.     
  169.     def insert(self, index, code):
  170.         self.data.insert(index, code)
  171.  
  172.     
  173.     def append(self, code):
  174.         self.data.append(code)
  175.  
  176.     
  177.     def getwidth(self):
  178.         if self.width:
  179.             return self.width
  180.         
  181.         lo = hi = 0x0L
  182.         UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY)
  183.         REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
  184.         for op, av in self.data:
  185.             if op is BRANCH:
  186.                 i = sys.maxint
  187.                 j = 0
  188.                 for av in av[1]:
  189.                     (l, h) = av.getwidth()
  190.                     i = min(i, l)
  191.                     j = max(j, h)
  192.                 
  193.                 lo = lo + i
  194.                 hi = hi + j
  195.                 continue
  196.             if op is CALL:
  197.                 (i, j) = av.getwidth()
  198.                 lo = lo + i
  199.                 hi = hi + j
  200.                 continue
  201.             if op is SUBPATTERN:
  202.                 (i, j) = av[1].getwidth()
  203.                 lo = lo + i
  204.                 hi = hi + j
  205.                 continue
  206.             if op in REPEATCODES:
  207.                 (i, j) = av[2].getwidth()
  208.                 lo = lo + long(i) * av[0]
  209.                 hi = hi + long(j) * av[1]
  210.                 continue
  211.             if op in UNITCODES:
  212.                 lo = lo + 1
  213.                 hi = hi + 1
  214.                 continue
  215.             if op == SUCCESS:
  216.                 break
  217.                 continue
  218.         
  219.         self.width = (int(min(lo, sys.maxint)), int(min(hi, sys.maxint)))
  220.         return self.width
  221.  
  222.  
  223.  
  224. class Tokenizer:
  225.     
  226.     def __init__(self, string):
  227.         self.string = string
  228.         self.index = 0
  229.         self._Tokenizer__next()
  230.  
  231.     
  232.     def __next(self):
  233.         if self.index >= len(self.string):
  234.             self.next = None
  235.             return None
  236.         
  237.         char = self.string[self.index]
  238.         if char[0] == '\\':
  239.             
  240.             try:
  241.                 c = self.string[self.index + 1]
  242.             except IndexError:
  243.                 raise error, 'bogus escape (end of line)'
  244.  
  245.             char = char + c
  246.         
  247.         self.index = self.index + len(char)
  248.         self.next = char
  249.  
  250.     
  251.     def match(self, char, skip = 1):
  252.         if char == self.next:
  253.             if skip:
  254.                 self._Tokenizer__next()
  255.             
  256.             return 1
  257.         
  258.         return 0
  259.  
  260.     
  261.     def get(self):
  262.         this = self.next
  263.         self._Tokenizer__next()
  264.         return this
  265.  
  266.     
  267.     def tell(self):
  268.         return (self.index, self.next)
  269.  
  270.     
  271.     def seek(self, index):
  272.         (self.index, self.next) = index
  273.  
  274.  
  275.  
  276. def isident(char):
  277.     if char <= char:
  278.         pass
  279.     elif not char <= 'z':
  280.         if char <= char:
  281.             pass
  282.         elif not char <= 'Z':
  283.             pass
  284.     return char == '_'
  285.  
  286.  
  287. def isdigit(char):
  288.     return None if char <= char else char <= '9'
  289.  
  290.  
  291. def isname(name):
  292.     if not isident(name[0]):
  293.         return False
  294.     
  295.     for char in name[1:]:
  296.         if not isident(char) and not isdigit(char):
  297.             return False
  298.             continue
  299.     
  300.     return True
  301.  
  302.  
  303. def _class_escape(source, escape):
  304.     code = ESCAPES.get(escape)
  305.     if code:
  306.         return code
  307.     
  308.     code = CATEGORIES.get(escape)
  309.     if code:
  310.         return code
  311.     
  312.     
  313.     try:
  314.         c = escape[1:2]
  315.         if c == 'x':
  316.             while source.next in HEXDIGITS and len(escape) < 4:
  317.                 escape = escape + source.get()
  318.             escape = escape[2:]
  319.             if len(escape) != 2:
  320.                 raise error, 'bogus escape: %s' % repr('\\' + escape)
  321.             
  322.             return (LITERAL, int(escape, 16) & 255)
  323.         elif c in OCTDIGITS:
  324.             while source.next in OCTDIGITS and len(escape) < 4:
  325.                 escape = escape + source.get()
  326.             escape = escape[1:]
  327.             return (LITERAL, int(escape, 8) & 255)
  328.         elif c in DIGITS:
  329.             raise error, 'bogus escape: %s' % repr(escape)
  330.         
  331.         if len(escape) == 2:
  332.             return (LITERAL, ord(escape[1]))
  333.     except ValueError:
  334.         pass
  335.  
  336.     raise error, 'bogus escape: %s' % repr(escape)
  337.  
  338.  
  339. def _escape(source, escape, state):
  340.     code = CATEGORIES.get(escape)
  341.     if code:
  342.         return code
  343.     
  344.     code = ESCAPES.get(escape)
  345.     if code:
  346.         return code
  347.     
  348.     
  349.     try:
  350.         c = escape[1:2]
  351.         if c == 'x':
  352.             while source.next in HEXDIGITS and len(escape) < 4:
  353.                 escape = escape + source.get()
  354.             if len(escape) != 4:
  355.                 raise ValueError
  356.             
  357.             return (LITERAL, int(escape[2:], 16) & 255)
  358.         elif c == '0':
  359.             while source.next in OCTDIGITS and len(escape) < 4:
  360.                 escape = escape + source.get()
  361.             return (LITERAL, int(escape[1:], 8) & 255)
  362.         elif c in DIGITS:
  363.             if source.next in DIGITS:
  364.                 escape = escape + source.get()
  365.                 if escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS:
  366.                     escape = escape + source.get()
  367.                     return (LITERAL, int(escape[1:], 8) & 255)
  368.                 
  369.             
  370.             group = int(escape[1:])
  371.             if group < state.groups:
  372.                 if not state.checkgroup(group):
  373.                     raise error, 'cannot refer to open group'
  374.                 
  375.                 return (GROUPREF, group)
  376.             
  377.             raise ValueError
  378.         
  379.         if len(escape) == 2:
  380.             return (LITERAL, ord(escape[1]))
  381.     except ValueError:
  382.         pass
  383.  
  384.     raise error, 'bogus escape: %s' % repr(escape)
  385.  
  386.  
  387. def _parse_sub(source, state, nested = 1):
  388.     items = []
  389.     itemsappend = items.append
  390.     sourcematch = source.match
  391.     while None:
  392.         if sourcematch('|'):
  393.             continue
  394.         
  395.         if not nested:
  396.             break
  397.         
  398.         if not (source.next) or sourcematch(')', 0):
  399.             break
  400.             continue
  401.         raise error, 'pattern not properly closed'
  402.         continue
  403.         if len(items) == 1:
  404.             return items[0]
  405.         
  406.     subpattern = SubPattern(state)
  407.     subpatternappend = subpattern.append
  408.     while None:
  409.         prefix = None
  410.         for item in items:
  411.             if not item:
  412.                 break
  413.             
  414.             if prefix is None:
  415.                 prefix = item[0]
  416.                 continue
  417.             if item[0] != prefix:
  418.                 break
  419.                 continue
  420.         else:
  421.             for item in items:
  422.                 del item[0]
  423.             
  424.         break
  425.         continue
  426.         for item in items:
  427.             if len(item) != 1 or item[0][0] != LITERAL:
  428.                 break
  429.                 continue
  430.         else:
  431.             set = []
  432.             setappend = set.append
  433.             for item in items:
  434.                 setappend(item[0])
  435.             
  436.             return subpattern
  437.     subpattern.append((BRANCH, (None, items)))
  438.     return subpattern
  439.  
  440.  
  441. def _parse_sub_cond(source, state, condgroup):
  442.     item_yes = _parse(source, state)
  443.     if source.match('|'):
  444.         item_no = _parse(source, state)
  445.         if source.match('|'):
  446.             raise error, 'conditional backref with more than two branches'
  447.         
  448.     else:
  449.         item_no = None
  450.     if source.next and not source.match(')', 0):
  451.         raise error, 'pattern not properly closed'
  452.     
  453.     subpattern = SubPattern(state)
  454.     subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no)))
  455.     return subpattern
  456.  
  457. _PATTERNENDERS = set('|)')
  458. _ASSERTCHARS = set('=!<')
  459. _LOOKBEHINDASSERTCHARS = set('=!')
  460. _REPEATCODES = set([
  461.     MIN_REPEAT,
  462.     MAX_REPEAT])
  463.  
  464. def _parse(source, state):
  465.     subpattern = SubPattern(state)
  466.     subpatternappend = subpattern.append
  467.     sourceget = source.get
  468.     sourcematch = source.match
  469.     _len = len
  470.     PATTERNENDERS = _PATTERNENDERS
  471.     ASSERTCHARS = _ASSERTCHARS
  472.     LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS
  473.     REPEATCODES = _REPEATCODES
  474.     while source.next in PATTERNENDERS:
  475.         break
  476.     this = sourceget()
  477.     if this is None:
  478.         break
  479.     
  480.     if state.flags & SRE_FLAG_VERBOSE:
  481.         if this in WHITESPACE:
  482.             continue
  483.         
  484.         if this == '#':
  485.             while None:
  486.                 this = sourceget()
  487.                 if this in (None, '\n'):
  488.                     break
  489.                     continue
  490.                 continue
  491.                 continue
  492.         this == '#'
  493.     
  494.     if this and this[0] not in SPECIAL_CHARS:
  495.         subpatternappend((LITERAL, ord(this)))
  496.         continue
  497.     if this == '[':
  498.         set = []
  499.         setappend = set.append
  500.         if sourcematch('^'):
  501.             setappend((NEGATE, None))
  502.         
  503.         start = set[:]
  504.         while None:
  505.             this = sourceget()
  506.             if this == ']' and set != start:
  507.                 break
  508.             elif this and this[0] == '\\':
  509.                 code1 = _class_escape(source, this)
  510.             elif this:
  511.                 code1 = (LITERAL, ord(this))
  512.             else:
  513.                 raise error, 'unexpected end of regular expression'
  514.             if sourcematch('-'):
  515.                 this = sourceget()
  516.                 if this == ']':
  517.                     if code1[0] is IN:
  518.                         code1 = code1[1][0]
  519.                     
  520.                     setappend(code1)
  521.                     setappend((LITERAL, ord('-')))
  522.                     break
  523.                 elif this:
  524.                     if this[0] == '\\':
  525.                         code2 = _class_escape(source, this)
  526.                     else:
  527.                         code2 = (LITERAL, ord(this))
  528.                     if code1[0] != LITERAL or code2[0] != LITERAL:
  529.                         raise error, 'bad character range'
  530.                     
  531.                     lo = code1[1]
  532.                     hi = code2[1]
  533.                     if hi < lo:
  534.                         raise error, 'bad character range'
  535.                     
  536.                     setappend((RANGE, (lo, hi)))
  537.                 else:
  538.                     raise error, 'unexpected end of regular expression'
  539.             if code1[0] is IN:
  540.                 code1 = code1[1][0]
  541.             
  542.             setappend(code1)
  543.             continue
  544.             if _len(set) == 1 and set[0][0] is LITERAL:
  545.                 subpatternappend(set[0])
  546.             elif _len(set) == 2 and set[0][0] is NEGATE and set[1][0] is LITERAL:
  547.                 subpatternappend((NOT_LITERAL, set[1][1]))
  548.             else:
  549.                 subpatternappend((IN, set))
  550.             set[1][0] is LITERAL
  551.             if this and this[0] in REPEAT_CHARS:
  552.                 if this == '?':
  553.                     (min, max) = (0, 1)
  554.                 elif this == '*':
  555.                     min = 0
  556.                     max = MAXREPEAT
  557.                 elif this == '+':
  558.                     min = 1
  559.                     max = MAXREPEAT
  560.                 elif this == '{':
  561.                     if source.next == '}':
  562.                         subpatternappend((LITERAL, ord(this)))
  563.                         continue
  564.                     
  565.                     here = source.tell()
  566.                     min = 0
  567.                     max = MAXREPEAT
  568.                     lo = hi = ''
  569.                     while source.next in DIGITS:
  570.                         lo = lo + source.get()
  571.                     if sourcematch(','):
  572.                         while source.next in DIGITS:
  573.                             hi = hi + sourceget()
  574.                     else:
  575.                         hi = lo
  576.                     if not sourcematch('}'):
  577.                         subpatternappend((LITERAL, ord(this)))
  578.                         source.seek(here)
  579.                         continue
  580.                     
  581.                     if lo:
  582.                         min = int(lo)
  583.                     
  584.                     if hi:
  585.                         max = int(hi)
  586.                     
  587.                     if max < min:
  588.                         raise error, 'bad repeat interval'
  589.                     
  590.                 else:
  591.                     raise error, 'not supported'
  592.                 if subpattern:
  593.                     item = subpattern[-1:]
  594.                 else:
  595.                     item = None
  596.                 if (not item or _len(item) == 1) and item[0][0] == AT:
  597.                     raise error, 'nothing to repeat'
  598.                 
  599.                 if item[0][0] in REPEATCODES:
  600.                     raise error, 'multiple repeat'
  601.                 
  602.                 if sourcematch('?'):
  603.                     subpattern[-1] = (MIN_REPEAT, (min, max, item))
  604.                 else:
  605.                     subpattern[-1] = (MAX_REPEAT, (min, max, item))
  606.     sourcematch('?')
  607.     if this == '.':
  608.         subpatternappend((ANY, None))
  609.         continue
  610.     if this == '(':
  611.         group = 1
  612.         name = None
  613.         condgroup = None
  614.         if sourcematch('?'):
  615.             group = 0
  616.             if sourcematch('P'):
  617.                 if sourcematch('<'):
  618.                     name = ''
  619.                     while None:
  620.                         char = sourceget()
  621.                         if char is None:
  622.                             raise error, 'unterminated name'
  623.                         
  624.                         if char == '>':
  625.                             break
  626.                         
  627.                         name = name + char
  628.                         continue
  629.                         group = 1
  630.                         if not isname(name):
  631.                             raise error, 'bad character in group name'
  632.                         
  633.                 isname(name)
  634.                 if sourcematch('='):
  635.                     name = ''
  636.                     while None:
  637.                         char = sourceget()
  638.                         if char is None:
  639.                             raise error, 'unterminated name'
  640.                         
  641.                         if char == ')':
  642.                             break
  643.                         
  644.                         name = name + char
  645.                         continue
  646.                         if not isname(name):
  647.                             raise error, 'bad character in group name'
  648.                         
  649.                     gid = state.groupdict.get(name)
  650.                     if gid is None:
  651.                         raise error, 'unknown group name'
  652.                     
  653.                     subpatternappend((GROUPREF, gid))
  654.                     continue
  655.                 else:
  656.                     char = sourceget()
  657.                     if char is None:
  658.                         raise error, 'unexpected end of pattern'
  659.                     
  660.                     raise error, 'unknown specifier: ?P%s' % char
  661.             elif sourcematch(':'):
  662.                 group = 2
  663.             elif sourcematch('#'):
  664.                 while source.next is None or source.next == ')':
  665.                     break
  666.                 sourcematch('?')
  667.                 sourceget()
  668.                 continue
  669.                 if not sourcematch(')'):
  670.                     raise error, 'unbalanced parenthesis'
  671.                     continue
  672.                 continue
  673.             elif source.next in ASSERTCHARS:
  674.                 char = sourceget()
  675.                 dir = 1
  676.                 if char == '<':
  677.                     if source.next not in LOOKBEHINDASSERTCHARS:
  678.                         raise error, 'syntax error'
  679.                     
  680.                     dir = -1
  681.                     char = sourceget()
  682.                 
  683.                 p = _parse_sub(source, state)
  684.                 if not sourcematch(')'):
  685.                     raise error, 'unbalanced parenthesis'
  686.                 
  687.                 if char == '=':
  688.                     subpatternappend((ASSERT, (dir, p)))
  689.                     continue
  690.                 subpatternappend((ASSERT_NOT, (dir, p)))
  691.                 continue
  692.             elif sourcematch('('):
  693.                 condname = ''
  694.                 while None:
  695.                     char = sourceget()
  696.                     if char is None:
  697.                         raise error, 'unterminated name'
  698.                     
  699.                     if char == ')':
  700.                         break
  701.                     
  702.                     condname = condname + char
  703.                     continue
  704.                     group = 2
  705.                     if isname(condname):
  706.                         condgroup = state.groupdict.get(condname)
  707.                         if condgroup is None:
  708.                             raise error, 'unknown group name'
  709.                         
  710.                     else:
  711.                         
  712.                         try:
  713.                             condgroup = int(condname)
  714.                         except ValueError:
  715.                             raise error, 'bad character in group name'
  716.                         except:
  717.                             None<EXCEPTION MATCH>ValueError
  718.                         
  719.  
  720.                         None<EXCEPTION MATCH>ValueError
  721.                         if source.next not in FLAGS:
  722.                             raise error, 'unexpected end of pattern'
  723.                         
  724.             while source.next in FLAGS:
  725.                 state.flags = state.flags | FLAGS[sourceget()]
  726.         
  727.         if group:
  728.             if group == 2:
  729.                 group = None
  730.             else:
  731.                 group = state.opengroup(name)
  732.             if condgroup:
  733.                 p = _parse_sub_cond(source, state, condgroup)
  734.             else:
  735.                 p = _parse_sub(source, state)
  736.             if not sourcematch(')'):
  737.                 raise error, 'unbalanced parenthesis'
  738.             
  739.             if group is not None:
  740.                 state.closegroup(group)
  741.             
  742.             subpatternappend((SUBPATTERN, (group, p)))
  743.         else:
  744.             while None:
  745.                 char = sourceget()
  746.                 if char is None:
  747.                     raise error, 'unexpected end of pattern'
  748.                 
  749.                 if char == ')':
  750.                     break
  751.                 
  752.                 raise error, 'unknown extension'
  753.                 continue
  754.                 continue
  755.                 if this == '^':
  756.                     subpatternappend((AT, AT_BEGINNING))
  757.                     continue
  758.                 if this == '$':
  759.                     subpattern.append((AT, AT_END))
  760.                     continue
  761.                 if this and this[0] == '\\':
  762.                     code = _escape(source, this, state)
  763.                     subpatternappend(code)
  764.                     continue
  765.                 raise error, 'parser error'
  766.                 continue
  767.                 return subpattern
  768.  
  769.  
  770. def parse(str, flags = 0, pattern = None):
  771.     source = Tokenizer(str)
  772.     if pattern is None:
  773.         pattern = Pattern()
  774.     
  775.     pattern.flags = flags
  776.     pattern.str = str
  777.     p = _parse_sub(source, pattern, 0)
  778.     tail = source.get()
  779.     if tail == ')':
  780.         raise error, 'unbalanced parenthesis'
  781.     elif tail:
  782.         raise error, 'bogus characters at end of regular expression'
  783.     
  784.     if flags & SRE_FLAG_DEBUG:
  785.         p.dump()
  786.     
  787.     if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
  788.         return parse(str, p.pattern.flags)
  789.     
  790.     return p
  791.  
  792.  
  793. def parse_template(source, pattern):
  794.     s = Tokenizer(source)
  795.     sget = s.get
  796.     p = []
  797.     a = p.append
  798.     
  799.     def literal(literal, p = p, pappend = a):
  800.         if p and p[-1][0] is LITERAL:
  801.             p[-1] = (LITERAL, p[-1][1] + literal)
  802.         else:
  803.             pappend((LITERAL, literal))
  804.  
  805.     sep = source[:0]
  806.     if type(sep) is type(''):
  807.         makechar = chr
  808.     else:
  809.         makechar = unichr
  810.     while None:
  811.         this = sget()
  812.         if this is None:
  813.             break
  814.         
  815.         if this and this[0] == '\\':
  816.             c = this[1:2]
  817.             if c == 'g':
  818.                 name = ''
  819.                 if s.match('<'):
  820.                     while None:
  821.                         char = sget()
  822.                         if char is None:
  823.                             raise error, 'unterminated group name'
  824.                         
  825.                         if char == '>':
  826.                             break
  827.                         
  828.                         name = name + char
  829.                         continue
  830.                 s.match('<')
  831.                 if not name:
  832.                     raise error, 'bad group name'
  833.                 
  834.                 
  835.                 try:
  836.                     index = int(name)
  837.                     if index < 0:
  838.                         raise error, 'negative group number'
  839.                 except ValueError:
  840.                     if not isname(name):
  841.                         raise error, 'bad character in group name'
  842.                     
  843.                     
  844.                     try:
  845.                         index = pattern.groupindex[name]
  846.                     except KeyError:
  847.                         raise IndexError, 'unknown group name'
  848.                     except:
  849.                         None<EXCEPTION MATCH>KeyError
  850.                     
  851.  
  852.                     None<EXCEPTION MATCH>KeyError
  853.  
  854.                 a((MARK, index))
  855.             elif c == '0':
  856.                 if s.next in OCTDIGITS:
  857.                     this = this + sget()
  858.                     if s.next in OCTDIGITS:
  859.                         this = this + sget()
  860.                     
  861.                 
  862.                 literal(makechar(int(this[1:], 8) & 255))
  863.             elif c in DIGITS:
  864.                 isoctal = False
  865.                 if s.next in DIGITS:
  866.                     this = this + sget()
  867.                     if c in OCTDIGITS and this[2] in OCTDIGITS and s.next in OCTDIGITS:
  868.                         this = this + sget()
  869.                         isoctal = True
  870.                         literal(makechar(int(this[1:], 8) & 255))
  871.                     
  872.                 
  873.                 if not isoctal:
  874.                     a((MARK, int(this[1:])))
  875.                 
  876.             else:
  877.                 
  878.                 try:
  879.                     this = makechar(ESCAPES[this][1])
  880.                 except KeyError:
  881.                     pass
  882.  
  883.                 literal(this)
  884.         literal(this)
  885.         continue
  886.         i = 0
  887.         groups = []
  888.         groupsappend = groups.append
  889.         literals = [
  890.             None] * len(p)
  891.         for c, s in p:
  892.             if c is MARK:
  893.                 groupsappend((i, s))
  894.             else:
  895.                 literals[i] = s
  896.             i = i + 1
  897.         
  898.     return (groups, literals)
  899.  
  900.  
  901. def expand_template(template, match):
  902.     g = match.group
  903.     sep = match.string[:0]
  904.     (groups, literals) = template
  905.     literals = literals[:]
  906.     
  907.     try:
  908.         for index, group in groups:
  909.             literals[index] = s = g(group)
  910.             if s is None:
  911.                 raise error, 'unmatched group'
  912.                 continue
  913.     except IndexError:
  914.         raise error, 'invalid group reference'
  915.  
  916.     return sep.join(literals)
  917.  
  918.